package com.cy.pj.sys.web.config;

import com.cy.pj.sys.service.realm.ShiroRealm;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfig {
    /**
     * 定义Realm对象，通过此对象访问数据库中的用户和权限信息，并进行封装。
     * @Bean注解描述方法时，表示方法的返回要交给spring管理，这个bean的名字默认
     * 为方法名。,还可以自己起名，例如@Bean("shiroRealm")*/
    @Bean
    public Realm realm() {
        return new ShiroRealm();
    }
    /**基于此对象定义过滤规则，例如哪些请求必须要认证，哪些请求不需要认证
     * ShiroFilterChainDefinition 此对象中定义了若干过滤器Filter,基于这
     * 些过滤器以及我们定义的过滤规则对业务进行实现。
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        //定义过滤链对象
        DefaultShiroFilterChainDefinition chainDefinition =
                new DefaultShiroFilterChainDefinition();
        //设置登录操作不需要认证(其中，anon表示匿名访问处理)
        chainDefinition.addPathDefinition("/user/login/**", "anon");
        //设置登出操作，登出以后要跳转到登录页面(其中,logout表示系统登出处理)
        chainDefinition.addPathDefinition("/user/logout", "logout");
        //设置哪些资源需要认证才可访问
        //这里表示对这个url(例如/user/**)，要调用过滤链中的哪个过滤器(例如authc)进行处理
        //chainDefinition.addPathDefinition("/user/**", "authc");
        //chainDefinition.addPathDefinition("/**", "authc");
        chainDefinition.addPathDefinition("/**", "user");
        //当我们访问一个需要认证以后才可以访问的资源时，但是你还没有认证，此时会跳转到登录页面
        return chainDefinition;
    }

    /**
     * 当将shiro中的注解RequiresPermissions放到控制层方法时需要配置此对象
     * ，并设置对控制层方法上的注解有效(例如@GetMapping)
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setUsePrefix(true);
        return advisorAutoProxyCreator;
    }
    /**会话session设置*/
    @Bean
    public SessionManager sessionManager(){
        DefaultWebSessionManager sessionManager=
                new DefaultWebSessionManager();
        //session 的超时时间
        sessionManager.setGlobalSessionTimeout(1000*60*60);//1 个小时
//        sessionManager.setGlobalSessionTimeout(2*60*1000);//2 分钟
        //删除无效 session
        sessionManager.setDeleteInvalidSessions(true);
        //当客户端 cookie 被禁用是否要设置 url 重写
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        return sessionManager;
    }
    /**记住我*/
    @Bean
    public RememberMeManager rememberMeManager(){
        CookieRememberMeManager rememberMeManager=new CookieRememberMeManager();
        SimpleCookie cookie=new SimpleCookie("rememberMe");
        cookie.setMaxAge(7*24*60*60);//设置cookie的生命周期
        rememberMeManager.setCookie(cookie);
        rememberMeManager.setCipherKey(
                Base64.decode("WGjHie9R114WBoCm3TAZ0g=="));
        return rememberMeManager;
    }
    /**配置授权缓存管理器，默认应用的缓存是shiro框架内置的缓存对象，
     * 缓存实现就是一个map.*/
    @Bean
    protected CacheManager shiroCacheManager() {
        return new MemoryConstrainedCacheManager();
    }

}
